//
//  sandboxTests.m
//  sandboxTests
//
//  Created by 杨岑 on 14/11/28.
//  Copyright (c) 2014年 杨岑. All rights reserved.
//

#import <Cocoa/Cocoa.h>
#import <XCTest/XCTest.h>
#import "Dummy.h"
#import "SingletonTest.h"


@interface sandboxTests : XCTestCase

@end

@implementation sandboxTests

- (void)setUp {
    [super setUp];
    // Put setup code here. This method is called before the invocation of each test method in the class.
}

- (void)tearDown {
    // Put teardown code here. This method is called after the invocation of each test method in the class.
    [super tearDown];
}

- (void)testDummy
{
    Dummy* dummy = [[Dummy alloc] init];
    NSLog(@">>>%@", dummy.array);
    [dummy test];
    
    dummy = nil;
    [dummy test];
}

- (void)testDictionary
{
    NSMutableDictionary* hash = [NSMutableDictionary dictionary];
    hash[@"a"] = @"aa";
    // Value for non-existing key is nil.
    NSLog(@"%@", hash[@"x"]);
    // Setting a key value to nil removes the key.
    hash[@"a"] = nil;
    NSLog(@"%@", hash[@"a"]);
}

- (void)testPWD
{
    NSArray* files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:@"." error:nil];
    NSLog(@"%@", files);
}

- (void)testNSData
{
    NSLog(@">>>%@", [NSData dataWithBytes:nil length:0]);
}

- (void)testDate
{
    NSDate* now = [NSDate date];
    NSDate* copy = [now copy];
    NSString* bkname = [NSString stringWithFormat:@"bk@%08lx.db", (long)copy.timeIntervalSince1970];
    NSLog(@"%@", bkname);
}

- (void)testNSDateFormatter
{
    NSDateFormatter* f = [[NSDateFormatter alloc] init];
    f.dateStyle = NSDateFormatterMediumStyle;
    f.timeStyle = NSDateFormatterMediumStyle;
    f.doesRelativeDateFormatting = YES;
    NSLog(@"Now: %@", [f stringFromDate:[NSDate date]]);
}

- (void)testSync
{
    @synchronized(self)
    {
        @synchronized(self)
        {
            NSLog(@"@synchroniz test");
        }
    }
}

- (void)testStringExt
{
    NSString* s1 = @"string abcd";
    NSString* s2 = @"string ";
    NSString* s3 = @"String ";
    NSString* s4 = @"xxx";
    
    XCTAssert([s1 startsWithNoCase:s2]);
    XCTAssert([s1 startsWith:s2]);
    
    XCTAssert([s1 startsWithNoCase:s3]);
    XCTAssert(![s1 startsWith:s3]);
    
    XCTAssert(![s1 startsWithNoCase:s4]);
    XCTAssert(![s1 startsWith:s4]);
    
    NSString* end1 = @"abcd";
    NSString* end2 = @"Abcd";
    NSString* end3 = @"xxx";
    
    XCTAssert([s1 endsWithNoCase:end1]);
    XCTAssert([s1 endsWith:end1]);
    
    XCTAssert([s1 endsWithNoCase:end2]);
    XCTAssert(![s1 endsWith:end2]);
    
    XCTAssert(![s1 endsWithNoCase:end3]);
    XCTAssert(![s1 endsWith:end3]);
}

- (void)testStringTrimming
{
    NSDictionary* tests = @{@"": @"", @" ": @"", @"\t": @"", @"\t \r\n":@"",
                            @"\t  test \t ": @"test"};
    for (NSString* s in tests)
    {
        NSString* t = [s trim];
        XCTAssert([t isEqualToString:tests[s]]);
    }

    tests = @{@"": @"", @" ": @"", @"\t": @"", @"\t \r\n":@"",
                            @"\t  test \t ": @"test \t "};
    for (NSString* s in tests)
    {
        NSString* t = [s trimLeft];
        XCTAssert([t isEqualToString:tests[s]]);
    }

    tests = @{@"": @"", @" ": @"", @"\t": @"", @"\t \r\n":@"",
                                @"\t  test \t ": @"\t  test"};
    for (NSString* s in tests)
    {
        NSString* t = [s trimRight];
        XCTAssert([t isEqualToString:tests[s]]);
    }
}

- (void)testPlistSerialization {
    NSString* file = [@"~/Library/Preferences/com.apple.spaces.plist" stringByExpandingTildeInPath];
    NSData* data = [NSData dataWithContentsOfFile:file];
    NSError* error;
    NSPropertyListFormat format = 0;
    id plist = [NSPropertyListSerialization propertyListWithData:data options:NSPropertyListImmutable format:&format error:&error];
    if (error) {
        NSLog(@"%@", error);
    }
    else {
        NSLog(@"%@", plist);
    }
}

- (void)testReadPlistWithDictionary {
    NSString* file = [@"~/Library/Preferences/com.apple.spaces.plist" stringByExpandingTildeInPath];
    NSLog(@"%@", file);
    NSDictionary* dic = [NSMutableDictionary dictionaryWithContentsOfFile:file];
    NSLog(@"%@", dic);
}

- (void)testReadPlistWithDictionary2 {
    NSBundle* myBundle = [NSBundle bundleForClass:[self class]];
    NSString* file = [[myBundle.resourcePath stringByDeletingLastPathComponent] stringByAppendingPathComponent:@"Info.plist"];
    NSLog(@"%@", file);
    NSDictionary* dic = [NSDictionary dictionaryWithContentsOfFile:file];
    NSLog(@"%@", dic);
}

- (void)testReadStringsFile{
    NSBundle* myBundle = [NSBundle bundleForClass:[self class]];
    NSString* file = [myBundle.resourcePath stringByAppendingPathComponent:@"Localizable.strings"];
    NSLog(@"%@", file);
    NSDictionary* dic = [NSDictionary dictionaryWithContentsOfFile:file];
    NSLog(@"%@", dic);
}

- (void)testSingleton {
    NSLog(@"SinletonTest");
    SingletonTest* s1 = [[SingletonTest alloc] init];
    NSLog(@"%@", s1);
    
    SingletonTest* s2 = [[SingletonTest alloc] init];
    NSLog(@"%@", s2);
    
    SingletonTest* s3 = [SingletonTest instance];
    NSLog(@"%@", s3);
}

- (void)testLocale
{
    NSArray* a = [NSLocale availableLocaleIdentifiers];
    NSArray* b = [a sortedArrayUsingComparator:^NSComparisonResult(NSString* a, NSString* b) {
        return [a caseInsensitiveCompare:b];
    }];
    NSLog(@"%@", b);
}

- (void)testUserDefaults
{
    NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
    //[defaults setObject:nil forKey:@"test"];
    //[defaults setBool:YES forKey:@"bool"];
    
    NSLog(@"bool: %d", [defaults boolForKey:@"bool"]);
    NSLog(@"test: %@", [defaults stringForKey:@"test"]);
    NSLog(@"object for bool: %@", [[defaults objectForKey:@"bool"] className]);
    //NSLog(@"%@", [defaults persistentDomainForName:@"com.apple.windowserver"]);
    //[defaults.dictionaryRepresentation.descriptionInStringsFileFormat writeToFile:@"/tmp/t" atomically:NO encoding:NSUTF8StringEncoding error:nil];
    //[defaults setBool:YES forKey:@"bool"];
}

- (void)testSearchPath
{
    NSLog(@"%@", [@"~" stringByExpandingTildeInPath]);
    NSLog(@"%@", NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, NO));
    NSLog(@"%@", NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES));
}

- (void)testNumberFormatter
{
    NSInteger num = 12345;
    NSNumberFormatter* fmt = [[NSNumberFormatter alloc] init];
    //fmt.thousandSeparator = @",";
    fmt.numberStyle = NSNumberFormatterDecimalStyle;
    fmt.hasThousandSeparators = YES;
    NSLog(@"%@ %@", fmt.locale.localeIdentifier, [fmt stringFromNumber:@(num)]);
}

- (void)testJSON
{
    NSError* error;
    //NSString* jsonString = [@"{ \"a\" : 1234 }" dataUsingEncoding:NSUTF8StringEncoding];
    NSString* jsonFile = [@"~/Downloads/browsedata" stringByExpandingTildeInPath];
    NSString* js = [NSString stringWithContentsOfFile:jsonFile encoding:NSUTF8StringEncoding error:&error];
    if (error)
    {
        NSLog(@"%@", error);
    }
    NSRange r1 = [js rangeOfString:@"browseData="];
    NSRange r2 = [js rangeOfString:@";})(window, 'BingGallery');" options:NSBackwardsSearch];
    NSUInteger length = r1.location + r1.length;
    NSString* jsonString = [js substringWithRange:NSMakeRange(length, r2.location - length)];
    NSData* data = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
    
    @try
    {
        error = nil;
        id o = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
        if (error)
        {
            NSLog(@"%@", error);
        }
        else NSLog(@"%@: %@", [o class], o);
    }
    @catch(NSException* ex)
    {
        NSLog(@"%@", ex);
    }
}

- (void)testBingJSON
{
    NSString* file = [@"~/Downloads/bing.json" stringByExpandingTildeInPath];
    NSData* data = [NSData dataWithContentsOfFile:file];
    if (data)
    {
        NSError* error;
        id o = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
        if (error)
        {
            NSLog(@"%@", error);
        }
        else NSLog(@"%@: %@", [o class], o);
    }
}

- (void)testDictionaryRemove
{
    NSMutableDictionary* dic = [NSMutableDictionary dictionary];
    [dic removeObjectForKey:@""];
    dic[@""] = nil;
}

- (void)testNSAttributedStringSize
{
    NSMutableParagraphStyle* paraStyle = [[NSMutableParagraphStyle alloc] init];
    paraStyle.lineBreakMode = NSLineBreakByCharWrapping;
    paraStyle.alignment = NSLeftTextAlignment;
    
    id a = @{NSFontAttributeName: [NSFont userFontOfSize:25],
             NSForegroundColorAttributeName: [NSColor redColor],
             NSParagraphStyleAttributeName: paraStyle
             };
    NSAttributedString* s = [[NSAttributedString alloc] initWithString:@"test string test test" attributes:a];
    NSLog(@"\nsize of %@:\n%f, %f", s, s.size.width, s.size.height);
    
    NSRect rect = [s boundingRectWithSize:NSMakeSize(100, FLT_MAX) options:0];
    NSLog(@"\nbounds: %f,%f", rect.size.width, rect.size.height);
}

- (void)testFMMoveItem
{
    char cwd[500];
    printf("%s\n", getcwd(cwd, sizeof(cwd)));
    
    NSFileManager* fm = [[NSFileManager alloc] init];
    NSError* error;
    
    [fm moveItemAtPath:@"/tmp/src" toPath:@"/tmp/dest" error:&error];
    if (error)
    {
        NSLog(@"%@", error);
    }
}

- (void)testStringCompare
{
    NSString* s = nil;
    NSLog(@"caseInsensitiveCompare to nil: %ld", [@"" caseInsensitiveCompare:s]);
}

- (void)testFileManagerRemoveItem
{
    NSError* error = nil;
    BOOL ok = [[NSFileManager defaultManager] removeItemAtPath:@"non" error:&error];
    NSLog(@"%@: %@", ok ? @"Success" : @"Failure", error);
    error = error.userInfo[NSUnderlyingErrorKey];
    XCTAssert(error && error.code == ENOENT);
}

- (void)testRegularExpression
{
    NSError* error = nil;
    NSString* pattern = @"\\\\(?:e|(?:033))\\[(\\d+)(;(\\d+))*m";
    NSLog(@"Pattern: %@", pattern);
    NSRegularExpression* re = [NSRegularExpression regularExpressionWithPattern:pattern options:0 error:&error];
    if (error)
    {
        NSLog(@"%@", error);
    }
    else
    {
        NSString* s = @"\\e[1;23;45mprompt\\033[0m";
        NSLog(@"String: %@", s);
        NSArray* a = [re matchesInString:s options:0 range:NSMakeRange(0, s.length)];
        for (NSTextCheckingResult* match in a)
        {
            NSLog(@"Match: %ld,%ld %ld captures", match.range.location, match.range.length, match.numberOfRanges);
            for (NSInteger i = 0; i < match.numberOfRanges; i++)
            {
                NSRange range = [match rangeAtIndex:i];
                if (range.location != NSNotFound)
                {
                    NSLog(@"capture #%ld: %ld,%ld:%@", i, range.location, range.length, [s substringWithRange:range]);
                }
                else
                {
                    NSLog(@"capture #%ld: none", i);
                }
            }
        }
    }
}

- (void)testStringFormatOctal
{
    unsigned char chars[] = {8, 16, 123, 0};
    for (const unsigned char* p = chars; *p; p++)
    {
        NSString* s = [NSString stringWithFormat:@"\\%03o", *p];
        NSLog(@"Octal of %u is: %@", *p, s);
    }
}

- (void)testStringUTF8
{
    NSString* s = @"😄";
    NSLog(@"%@.length = %ld", s, s.length);
    for (NSInteger i = 0; i < s.length; i++)
    {
        printf("%04x,", [s characterAtIndex:i]);
    }
    puts("");
    for (NSInteger i = 0; i < strlen(s.UTF8String); i++)
    {
        printf("%02x,", s.UTF8String[i] & 0xff);
    }
    puts("");
}

- (void)test
{
    NSLog(@"__FUNCTION__: %s", __PRETTY_FUNCTION__);

    //NSError* error = nil;
    //NSString* s = [@"~/Documents" stringByExpandingTildeInPath];
    //NSArray* a = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:s error:&error];
    //NSLog(@"%@", a);
}

@end


